フロントエンド環境をS3にデプロイするCodePipelineをCloudFormationで作成する
はじめに
フロントエンド環境や静的なサイトをS3 + CloudFrontで配信するというケースも多いかと思います。CodeCommitにホストされたフロントエンドのソースコードをビルドしてS3にデプロイするCodePipelineをCloudFormationで作成してみました。
前提と作成するリソース
デプロイ先のS3とCloudFrontとフロントエンドのソースコードをホストするCodeCommitリポジトリは作成されているものとします。
今回はそれ以外のリソースをCloudFormationで作成します。具体的には以下のリソースをCloudFormationで作成します。
- CodeBuild
- CodeBuildのIAMロール
- ビルド成果物を格納するS3バケット
- CodePipeline
- CodePipelineのIAMロール
CloudFormationテンプレート
今回はリポジトリにpushしたタイミングでデプロイが実行されないようにPollForSourceChanges
をfalse
にしています。
AWSTemplateFormatVersion: 2010-09-09 Description: CodePipeline deploy example Parameters: ServiceName: Description: deploy-pipeline-example Type: String Default: deploy-pipeline-example Resources: # ビルド成果物を格納するS3 ArtifactsBucket: Type: AWS::S3::Bucket Properties: BucketName: !Sub ${ServiceName}-artifacts LifecycleConfiguration: Rules: - Id: DeleteRule Status: Enabled ExpirationInDays: 7 # CodeBuild CodeBuildProject: Type: AWS::CodeBuild::Project Properties: Name: !Sub ${ServiceName} Artifacts: Type: CODEPIPELINE Source: Type: CODEPIPELINE Environment: ComputeType: BUILD_GENERAL1_SMALL Image: aws/codebuild/standard:3.0 PrivilegedMode: false Type: LINUX_CONTAINER ServiceRole: !GetAtt CodeBuildServiceRole.Arn # CodeBuildのIAMロール CodeBuildServiceRole: Type: AWS::IAM::Role Properties: RoleName: !Sub ${ServiceName} Policies: - PolicyName: !Sub ${ServiceName}-CodeBuild-ServiceRolePolicy PolicyDocument: Version: '2012-10-17' Statement: - Action: - logs:CreateLogGroup - logs:CreateLogStream - logs:PutLogEvents Resource: - !Sub arn:aws:logs:ap-northeast-1:${AWS::AccountId}:log-group:/aws/codebuild/${ServiceName}:* Effect: Allow - Action: - codebuild:CreateReportGroup - codebuild:CreateReport - codebuild:UpdateReport - codebuild:BatchPutTestCases Resource: - !Sub arn:aws:logs:ap-northeast-1:${AWS::AccountId}:log-group:/aws/codebuild/${ServiceName}:* Effect: Allow - Action: - s3:PutObject - s3:GetObject - s3:GetObjectVersion - s3:GetBucketAcl - s3:GetBucketLocation - s3:ListBucket Resource: - '*' Effect: Allow - Action: - cloudformation:DescribeStackResources Resource: - '*' Effect: Allow - Action: - cloudfront:CreateInvalidation Resource: - '*' Effect: Allow AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Sid: '' Effect: Allow Principal: Service: codebuild.amazonaws.com Action: sts:AssumeRole # CodePipeline CodePipelineProject: Type: AWS::CodePipeline::Pipeline Properties: Name: !Sub ${ServiceName} RoleArn: !GetAtt CodePipelineServiceRole.Arn Stages: - Name: Source Actions: - Name: SourceAction ActionTypeId: Category: Source Owner: AWS Version: 1 Provider: CodeCommit OutputArtifacts: - Name: SourceArtifact # デプロイもとのCodeCommitのリポジトリとブランチ Configuration: RepositoryName: <デプロイもとのリポジトリ> BranchName: master # push時に自動でデプロイされないようにする PollForSourceChanges: false RunOrder: 1 - Name: Build Actions: - Name: BuildAction InputArtifacts: - Name: SourceArtifact OutputArtifacts: - Name: BuildArtifact ActionTypeId: Category: Build Owner: AWS Version: 1 Provider: CodeBuild Configuration: ProjectName: !Ref CodeBuildProject RunOrder: 2 ArtifactStore: Type: S3 Location: !Ref ArtifactsBucket # CodePipelineのIAMロール CodePipelineServiceRole: Type: AWS::IAM::Role Properties: RoleName: !Sub ${ServiceName}-CodePipelineServiceRole Policies: - PolicyName: !Sub ${ServiceName}-CodePipelineServiceRolePolicy PolicyDocument: Version: '2012-10-17' Statement: - Action: - s3:GetObject - s3:GetObjectVersion - s3:GetBucketVersioning Resource: - '*' Effect: Allow - Action: - s3:PutObject Resource: - arn:aws:s3:::codepipeline* Effect: Allow - Action: - codecommit:CancelUploadArchive - codecommit:GetBranch - codecommit:GetCommit - codecommit:GetUploadArchiveStatus - codecommit:UploadArchive Resource: - '*' Effect: Allow - Action: - codebuild:BatchGetBuilds - codebuild:StartBuild Resource: - '*' Effect: Allow - Action: - codedeploy:CreateDeployment - codedeploy:GetApplication - codedeploy:GetApplicationRevision - codedeploy:GetDeployment - codedeploy:GetDeploymentConfig - codedeploy:RegisterApplicationRevision Resource: - '*' Effect: Allow - Action: - codestar-connections:UseConnection Resource: - '*' Effect: Allow - Action: - s3:* Resource: - '*' Effect: Allow AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: - codepipeline.amazonaws.com Action: - sts:AssumeRole
buildspec.yaml
次に、デプロイするリポジトリにbuildspec.yaml
を作成します。
必要な依存ライブラリのインストールとテストを行った後にnpm run build
で静的ページが生成されるという想定で書いています。ビルド時にCloudFrontのキャッシュをクリアするコマンドも含めています。
version: 0.2 phases: install: runtime-versions: nodejs: 12 commands: # 静的サイトのビルドやテストなど - npm install - npm run test - npm run build build: commands: # npm run build の結果がdistディレクトリに出力されるという前提 - aws s3 sync dist s3://<デプロイ先のS3バケット> - aws cloudfront create-invalidation --distribution-id <キャッシュクリアするCloudFrontのDestributionID> --paths '/*'
デプロイする
CodePipelineから作成されたパイプラインを選択して「変更をリリースする」を選択します。
デプロイが完了するとS3にファイルがアップロードされていることが確認できます。また、CloudFrontに割り当てているドメインにアクセスすると変更内容が反映されたサイトが表示されます。